Conversation
2a6fafe to
dc78c62
Compare
… key parsing
Before this change, `./jcpan -t Digest::SHA3` installed the CPAN module
but 11 of 14 tests failed with "Undefined subroutine &Digest::SHA3::*"
because Digest::SHA3 is an XS module with no PerlOnJava backend.
This PR:
1. Adds Bouncy Castle (bcprov-jdk18on + bcpkix-jdk18on 1.78.1) as a
mandatory runtime dependency. See dev/modules/digest_sha3.md for the
analysis of why BC is the right choice (bit-level input + SHAKE XOFs
+ state copy, none of which the JDK provides for SHA-3).
2. Adds src/main/java/org/perlonjava/runtime/perlmodule/DigestSHA3.java
— a BC-backed Keccak wrapper implementing the full XS interface of
CPAN Digest-SHA3-1.05 (newSHA3, shainit, sharewind, shawrite, add,
digest, hexdigest, b64digest, squeeze, clone, hashsize, algorithm,
and the 18 one-shot functions sha3_224..shake256_base64).
The wrapper subclasses KeccakDigest directly and applies the SHA-3
("01") and SHAKE ("1111") domain separators in Java, because
SHA3Digest.doFinal and SHAKEDigest.doOutput call absorbBits
internally, which fails after we've already flushed a non-byte-
aligned reservoir.
A bit reservoir supports multi-call non-byte-aligned add_bits() —
the CPAN `bitorder.t` test does e.g. `->add_bits("0")->add_bits("1")
->add_bits("1")` which BC cannot handle directly.
3. Refactors NetSSLeay.parsePrivateKeyDer to use BC's PrivateKeyInfo +
JcaPEMKeyConverter. Replaces a trial-and-error loop over {RSA, EC,
DSA, EdDSA} KeyFactory.generatePrivate calls plus a hand-rolled
PKCS#1→PKCS#8 DER wrapper (wrapPkcs1InPkcs8, now deleted). The
AlgorithmIdentifier auto-detection in PrivateKeyInfo is correct by
construction and now supports Ed25519/Ed448 keys for free.
4. Resolves the "adopt Bouncy Castle?" open question in
dev/modules/netssleay_complete.md. The remaining hand-rolled DER
code (CSR builder, X509 extension encoders, RDNs, SAN encoding)
stays for this PR — it's extensively used and has full test
coverage; incremental BC ports are follow-up work.
Test results:
- `./jcpan -t Digest::SHA3`: 14/14 test files pass (33 subtests),
including all bit-level and SHAKE tests.
- `prove -e ./jperl src/test/resources/unit/netssleay_*.t`:
2553/2553 tests pass (no regressions in private-key parsing).
- `make`: all unit tests green.
See dev/modules/digest_sha3.md for the full design rationale and the
per-step implementation log.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ateKey_file CTX_use_PrivateKey_file previously called loadPrivateKeyFile (which invokes the password callback) and then re-opened the PEM and re-invoked the callback to populate ctxState.loadedPrivateKey for buildSslContext. This broke t/local/05_passwd_cb.t, which counts callback invocations: not ok 17 - different cbs per ctx work # each cb called 2x, expected 1 not ok 21 - callback1 called 2 times # got: '3' expected: '2' Plus spurious "Bad plan: planned 36 tests but ran 40" because the extra callback calls ran their own is()/ok() assertions. Fix: loadPrivateKeyFile now takes an optional SslCtxState and populates loadedPrivateKey + clears the cached SSLContext in a single pass. The callback runs exactly once per load. use_PrivateKey_file (SSL-level) benefits too — it now also populates the underlying CTX's key so the KeyManager sees it. Test results on t/local/05_passwd_cb.t: before: Tests: 40 Failed: 6 Parse errors: planned 36 ran 40 after: Tests: 36 Failed: 0 All tests successful. Full Net-SSLeay bundled suite: 47 files, 2326 tests, all pass. ./jcpan -t Digest::SHA3: 33/33 still green. make: green. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cefa787 to
56c79b7
Compare
The Gradle build (`make`, `make dev`) works locally because `build.gradle` + `libs.versions.toml` were updated in the initial commit. But the CI workflow uses Maven (`make ci` → `mvn`), and `pom.xml` was not updated, so CI failed with package org.bouncycastle.crypto.digests does not exist package org.bouncycastle.asn1.pkcs does not exist ... Add `bcprov-jdk18on` + `bcpkix-jdk18on` 1.78.1 to `pom.xml` to match `libs.versions.toml`. Verified with `mvn -q compile`. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports
Digest::SHA3to PerlOnJava via Bouncy Castle, and uses thenewly-added dependency to clean up private-key DER parsing in
NetSSLeay.java. Seedev/modules/digest_sha3.mdfor the fulldesign rationale.
Before this change,
./jcpan -t Digest::SHA3installed the CPANdistribution but failed 11/14 tests with
Undefined subroutine &Digest::SHA3::newSHA3etc., becauseDigest::SHA3is an XS moduleand PerlOnJava had no Java-side port.
What's in this PR
Dependency: adds
bcprov-jdk18on+bcpkix-jdk18onv1.78.1in
gradle/libs.versions.tomlandbuild.gradle.DigestSHA3.java(new): BC-backedKeccakwrapperimplementing the full XS interface of CPAN
Digest-SHA3-1.05(
newSHA3,shainit,sharewind,shawrite,add,digest,hexdigest,b64digest,squeeze,clone,hashsize,algorithm, and the 18 one-shot functions fromsha3_224throughshake256_base64).KeccakDigestdirectly and applies the SHA-3 ("01")and SHAKE ("1111") domain separators in Java —
SHA3Digest.doFinaland
SHAKEDigest.doOutputcallabsorbBitsinternally, whichfails after we've already flushed a non-byte-aligned reservoir.
add_bits—CPAN
bitorder.tdoes->add_bits("0")->add_bits("1")->add_bits("1")which BC cannot handle through
absorbBitsalone.lib/Digest/SHA3.pmcalls
XSLoader::load('Digest::SHA3')which dispatches to ourJava class via
XSLoader.java.NetSSLeay.parsePrivateKeyDerrefactor: replaces atrial-and-error loop over
{RSA, EC, DSA, EdDSA}KeyFactorycalls plus a hand-rolled PKCS#1→PKCS#8 DER wrapper with
PrivateKeyInfo.getInstance+JcaPEMKeyConverter. Auto-detectsthe algorithm from the DER
AlgorithmIdentifierand now supportsEd25519/Ed448 keys for free. Deletes
wrapPkcs1InPkcs8and itslocal DER helpers.
Doc updates:
dev/modules/digest_sha3.md(new): design + implementation log.dev/modules/netssleay_complete.md: resolves the "adopt BouncyCastle?" open question and updates the runtime-dependencies
section.
Explicitly out of scope (future PRs)
JcaPKCS10CertificationRequestBuilderandorg.bouncycastle.asn1.*.The remaining hand-rolled DER code is extensively used and fully
tested; a mechanical BC port deserves its own focused PR.
Digest::SHA.add_bitspartial-byte handling (BC doesn'texpose bit-level SHA-2 primitives; would need reflection or a
hand-rolled compression loop).
Digest::Keccak,Digest::BLAKE2,Digest::BLAKE3,Digest::HMAC_SHA3_*,Crypt::OpenSSL::AES,Crypt::CBCbackends,Crypt::JWT.Test plan
./jcpan -t Digest::SHA3→ 14/14 test files pass (33 subtests),including
t/bit-sha3-{224,256,384,512}.t,t/bit-shake{128,256}.t,t/bitorder.t,t/sha3-{224,256,384,512}.t.prove -e ./jperl src/test/resources/unit/netssleay_*.t→2553/2553 tests pass (no regressions in the BC-based
parsePrivateKeyDer).make→ all unit tests green.Size impact
+8 MBforbcprov-jdk18on,+3 MBforbcpkix-jdk18on. Modestcompared to the existing
icu4j(~12 MB).bc-fips.Generated with Devin